<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8" />
    <title>统一地图平台</title><link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />
    <style>
        body {
            margin: 0;
            padding: 0;
        }

        #mapui {
            position: absolute;
            top: 0;
            bottom: 0;
            width: 100%;
        }

        .overlay {
            position: absolute;
            top: 10px;
            left: 10px;
        }

        .overlay button {
            font: 600 12px/20px 'Helvetica Neue', Arial, Helvetica, sans-serif;
            background-color: #3386c0;
            color: #fff;
            display: inline-block;
            margin: 0;
            padding: 10px 20px;
            border: none;
            cursor: pointer;
            border-radius: 3px;
        }

        .overlay button:hover {
            background-color: #4ea0da;
        }
    </style>
</head>

<body>
    <div id="mapui"></div>
    <div class="overlay">
        <button id="replay">重放</button>
    </div>
    <div class="overlay" style=" left: 105px;">
        <button id="pause">暂停</button>
    </div>
    <script src="./js_example/script/map.min.js"></script>
    <script src="./js_example/script/demo.js"></script>
    <script src="./js_thematic_map_example/script/turf/turf.min.js"></script>
    <script src="./js_thematic_map_example/script/include-mapboxgl.js"></script>

    <script>

        var amap = null;
        var that = this;
        var animateId = null;



        // 折线
        var line = [[-124.414, 47.776], [-118.07923444196548, 38.684632819828245], [-113.643229725237, 37.42941415280371], [-109.12261705435526, 40.002369960656694], [-115.53754647700708, 40.397052480700246], [-99.91103258092194, 29.60885242216543], [-95.26801747727872, 48.63523761489001], [-90.63422968625943, 40.47588967948084], [-86.03495663923619, 45.1327214927582], [-76.49386585228416, 39.60977319896456], [-77.03200000000044, 30.91300000000006], [-52.7578125, 46.0836931], [-42.7578125, 20.0836931], [9.8170257, 44.9569063], [12.8170257, 15.9569063]];

        var loadingIndex = 0;
        // 添加航线数据
        var origin = line[0];

        var counter = 0;

        let aLength = line.length;

        var nstep = 200;
        var newroute = getRoute({
            'type': 'Feature',
            'geometry': {
                'type': 'LineString',
                'coordinates': line
            }
        }, nstep, { units: 'kilometers' })

        var steps = newroute.geometry.coordinates.length - 1

        var route = {
            'type': 'FeatureCollection',
            'features': [
                {
                    'type': 'Feature',
                    'geometry': {
                        'type': 'LineString',
                        'coordinates': [origin]
                    }
                }
            ]
        };


        // 沿着航线添加一个移动的点， 这个点从起始点运动到终点。
        var point = {
            'type': 'FeatureCollection',
            'features': [
                {
                    'type': 'Feature',
                    'properties': {},
                    'geometry': {
                        'type': 'Point',
                        'coordinates': origin
                    }
                }
            ]
        };

        // 转折点
        var turningPoint = {
            'type': 'FeatureCollection',
            'features': [
                {
                    'type': 'Feature',
                    'properties': {},
                    'geometry': {
                        'type': 'Point',
                        'coordinates': origin
                    }
                }
            ]
        };


        // 确定底图
        map.Factory.create('mapui', {
            center: [-56, 37.8],
            fullExtent: {
                xmin: 90.992204,
                ymin: 10.979711,
                xmax: 120.5338915,
                ymax: 50.543712
            },
            zoom: 2,
            projection: 'EPSG:4326',
            strategy: ['mapboxgl', 'openlayers'],
            style: style,
        }, (o) => {
            amap = o;

            amap.pmap.addSource('route', {
                'type': 'geojson',
                'data': route
            });

            amap.pmap.addSource('point', {
                'type': 'geojson',
                'data': point
            });

            amap.pmap.addSource('turning-point', {
                'type': 'geojson',
                'data': turningPoint
            });

            amap.pmap.loadImage('./js_thematic_map_example/images/redCar.png', function (error, image) {
                if (error) throw error;
                amap.pmap.addImage('car', image);
            });

            // 在 addLayer 这里，选择合适的线样式，图标样式， 把航线及飞行动画效果最终呈现在地图上。 
            // 我设置了3条重叠的但样式不一样的 Line 来创造发光的航线！
            amap.pmap.addLayer({
                'id': 'route',
                'source': 'route',
                'type': 'line',
                'paint': {
                    'line-width': 8,
                    'line-blur': 3,
                    'line-opacity': 0.2,

                    'line-color': '#007cbf'
                }
            });

            amap.pmap.addLayer({
                'id': 'route2',
                'source': 'route',
                'type': 'line',
                'paint': {
                    'line-width': 4,
                    'line-blur': 3,
                    'line-opacity': 0.4,

                    'line-color': '#009df2'
                }
            });

            amap.pmap.addLayer({
                'id': 'route3',
                'source': 'route',
                'type': 'line',
                'paint': {
                    'line-width': 1,
                    'line-blur': 1,
                    'line-opacity': 1,
                    'line-color': '#fff'
                }
            });

            // 还要在地图上添加飞行动画！我直接用了 Mapbox 自带的 Icon—airport-15。
            amap.pmap.addLayer({
                'id': 'point',
                'source': 'point',
                'type': 'symbol',
                'layout': {
                    'icon-image': 'car',
                    'icon-rotate': ['get', 'bearing'],
                    'icon-rotation-alignment': 'map',
                    'icon-allow-overlap': true,
                    'icon-ignore-placement': true
                }
            });

            // 转折点添加关键点
            amap.pmap.addLayer({
                'id': 'turning-point',
                'source': 'turning-point',
                'type': 'circle',
                'paint': {
                    'circle-radius': 3,
                    'circle-color': '#fbb03b'
                }
            });

            // 执行 animate 函数
            that.animate(counter);

            // 重置按钮添加事件
            document.getElementById('replay').addEventListener('click', function () {
                document.getElementById("pause").disabled = false;

                if (animateId) {
                    cancelAnimationFrame(animateId)
                }

                // 重置线数据源
                route.features[0].geometry.coordinates = [origin]
                amap.pmap.getSource('route').setData(route)

                // 重置转折点数据源
                turningPoint.features = [{
                    'type': 'Feature',
                    'geometry': {
                        'type': 'Point',
                        'coordinates': origin
                    }
                }];
                amap.pmap.getSource('turning-point').setData(turningPoint)

                counter = 0;
                loadingIndex = 0;

                that.animate(counter);
            });

            // 暂停按钮添加事件
            document.getElementById('pause').addEventListener('click', function () {
                var value = document.getElementById('pause').innerText
                if (value == '暂停') {
                    if (animateId) {
                        document.getElementById('pause').innerText = '恢复'
                        cancelAnimationFrame(animateId)
                    }
                } else if (value == '恢复') {
                    document.getElementById('pause').innerText = '暂停'
                    requestAnimationFrame(animate);
                }
            });

        });


        // animate 函数
        function animate() {

            var newLine = newroute.geometry.coordinates;
            var lnglat = newLine[counter]

            // 基于计数器表示的点几何更新到新的位置访问弧的索引。
            point.features[0].geometry.coordinates = lnglat;

            //计算方向角，以确保图标旋转以匹配路线圆弧
            //用当前点和下一点之间来计算方向角
            //在弧的末端使用上一个点和当前点
            point.features[0].properties.bearing = turf.bearing(
                turf.point(newLine[counter >= steps ? counter - 1 : counter]),
                turf.point(newLine[counter >= steps ? counter : counter + 1])
            );

            // 更新线坐标
            route.features[0].geometry.coordinates.push(lnglat)

            // 更新点位置和线
            amap.pmap.getSource('point').setData(point);
            amap.pmap.getSource('route').setData(route)


            if (loadingIndex < aLength && lnglat[0] == line[loadingIndex][0] && lnglat[1] == line[loadingIndex][1]) {
                if (loadingIndex == 0) {
                    turningPoint.features = [{
                        'type': 'Feature',
                        'geometry': {
                            'type': 'Point',
                            'coordinates': origin
                        }
                    }];
                } else {
                    turningPoint.features.push({
                        'type': 'Feature',
                        'geometry': {
                            'type': 'Point',
                            'coordinates': lnglat
                        }
                    });
                }
                amap.pmap.getSource('turning-point').setData(turningPoint);
                loadingIndex++;
            }

            if (counter < steps) {
                animateId = requestAnimationFrame(animate);
            } else {
                document.getElementById("pause").disabled = true;
            }

            counter = counter + 1;
        }



        //线打散
        function lineMore(from, to, distance, splitLength, units) {

            var step = parseInt(distance / splitLength)
            var leftLength = distance - step * splitLength
            console.log(distance + "," + splitLength + "," + step + "," + leftLength)

            var rings = []
            var route = turf.lineString([from.geometry.coordinates, to.geometry.coordinates])
            for (let i = 1; i <= step; i++) {
                let nlength = i * splitLength
                let pnt = turf.along(route, nlength, { units: 'kilometers' });
                rings.push(pnt.geometry.coordinates)
            }
            if (leftLength > 0) {
                rings.push(to.geometry.coordinates)
            }
            return rings
        }

        function getRoute(route, nstep, units) {
            var newroute = {
                "type": "Feature",
                "geometry": {
                    "type": "LineString",
                    "coordinates": []
                }
            }
            var lineDistance = turf.lineDistance(route,);
            var nDistance = lineDistance / nstep;
            for (let i = 0; i < aLength - 1; i++) {
                var from = turf.point(route.geometry.coordinates[i]);
                var to = turf.point(route.geometry.coordinates[i + 1]);
                let lDistance = turf.distance(from, to, units);
                if (i == 0) {
                    newroute.geometry.coordinates.push(route.geometry.coordinates[0])
                }
                if (lDistance > nDistance) {
                    let rings = lineMore(from, to, lDistance, nDistance, units)
                    newroute.geometry.coordinates = newroute.geometry.coordinates.concat(rings)
                } else {
                    newroute.geometry.coordinates.push(route.geometry.coordinates[i + 1])
                }
            }
            return newroute
        }
    </script>
</body>

</html>